using System;
using System.Windows;
using System.Windows.Media;
using System.Collections.Generic;
using System.Text;

using System.Windows.Controls;

namespace Microsoft.PowerShell.CmdletManagement
{
    internal static class CmdletDesignerUtils
    {
        internal static void HandleException(string title, string context, Exception exc)
        {
            if (String.IsNullOrEmpty(title))
            {
                title = "Error";
            }

            if (String.IsNullOrEmpty(context))
            {
                context = "Could not execute command.";
            }

            string message = context;
            if (exc != null)
            {
                message += "\n\n" + exc.Message;
            }
            message += "\n\n" + "Please see http://TODO_SUPPORT_PAGE for additional details.";
            
            MessageBox.Show(message, title);
        }
    
        internal static void ResizeColumns(ListView listView, string fillColumn)
        {
            if (listView == null)
                return;

            GridView gridView = listView.View as GridView;

            if ((gridView != null) && (listView.ActualWidth > 0))
            {
                double availableWidth = listView.ActualWidth;
                int fillIndex = -1;

                for (int columnIndex = 0; columnIndex < gridView.Columns.Count; columnIndex++)
                {
                    GridViewColumn column = gridView.Columns[columnIndex];

                    string header = column.Header as String;
                    if(header == null)
                        header = ((GridViewColumnHeader)column.Header).Content as String;

                    if (header != fillColumn)
                    {
                        column.Width = column.ActualWidth;
                        column.Width = Double.NaN;
                        availableWidth -= column.ActualWidth;
                    }
                    else
                    {
                        fillIndex = columnIndex;
                    }
                }

                // Adjustment for margins
                availableWidth -= 6;

                if ((fillIndex != -1) && (availableWidth > 0))
                {
                    gridView.Columns[fillIndex].Width = availableWidth;
                }
            }
        }

        internal static bool DoesSearchMatchCmdlet(PsSpecCmdlet cmdlet, string searchText)
        {
            string cmdletName = cmdlet.Verb + "-" + cmdlet.Noun;

            // Trimmed search and combinedCmdletName let users find the Get-Foo
            // cmdlet by typing:
            // "GetFoo" and "Get Foo"
            string trimmedSearch = searchText.Replace(" ", "");
            trimmedSearch = trimmedSearch.Replace("-", "");
            string combinedCmdletName = cmdletName.Replace("-", "");

            if (
                (String.IsNullOrEmpty(searchText)) ||
                (searchText == "Search") ||
                (cmdletName.IndexOf(searchText, StringComparison.InvariantCultureIgnoreCase) >= 0) ||
                (combinedCmdletName.IndexOf(trimmedSearch, StringComparison.InvariantCultureIgnoreCase) >= 0)
                )
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        internal static bool DoesSearchMatchProject(PsSpecProject project, string searchText)
        {
            string projectName = project.Name;

            // Trimmed search and combinedProjectName let users find the PowerShell-Foo
            // project by typing:
            // "PowerShellFoo" and "PowerShell Foo"
            string trimmedSearch = searchText.Replace(" ", "");
            trimmedSearch = trimmedSearch.Replace("-", "");
            string combinedProjectName = projectName.Replace("-", "");

            if (
                (String.IsNullOrEmpty(searchText)) ||
                (searchText == "Search") ||
                (projectName.IndexOf(searchText, StringComparison.InvariantCultureIgnoreCase) >= 0) ||
                (combinedProjectName.IndexOf(trimmedSearch, StringComparison.InvariantCultureIgnoreCase) >= 0)
                )
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        internal static bool IsInRole(PsSpecProjectRole role, System.Windows.Application application)
        {
            switch (role)
            {
                case PsSpecProjectRole.ProjectOwner: return (bool)application.Properties["IsProjectOwner"];
                case PsSpecProjectRole.SpecWriter: return (bool)application.Properties["IsSpecWriter"];
                case PsSpecProjectRole.HelpWriter: return (bool)application.Properties["IsHelpWriter"];
            }

            return false;
        }

        internal static void DisableAllCustomControls(FrameworkElement current)
        {
            ExtendedTextBlock extendedTextBlock = current as ExtendedTextBlock;
            if (extendedTextBlock != null)
            {
                extendedTextBlock.IsReadOnly = true;
            }

            FreeTextExtendedTextBlock freeTextExtendedTextBlock = current as FreeTextExtendedTextBlock;
            if (freeTextExtendedTextBlock != null)
            {
                freeTextExtendedTextBlock.IsReadOnly = true;
            }

            ExtendedCheckBox extendedCheckBox = current as ExtendedCheckBox;
            if (extendedCheckBox != null)
            {
                extendedCheckBox.IsReadOnly = true;
            }

            ExtendedListBox extendedListBox = current as ExtendedListBox;
            if (extendedListBox != null)
            {
                extendedListBox.IsReadOnly = true;
            }

            ParameterSetGroupingEditor parameterSetGroupingEditor = current as ParameterSetGroupingEditor;
            if (parameterSetGroupingEditor != null)
            {
                parameterSetGroupingEditor.IsReadOnly = true;
            }

            SpecExamplesControl specExamples = current as SpecExamplesControl;
            if (specExamples != null)
            {
                specExamples.HelpExamplesPanel.IsEnabled = false;
            }

            foreach (FrameworkElement child in EnumerateAllControls(current))
            {
                DisableAllCustomControls(child);
            }
        }

        // Find a child of the markup for an item
        internal static childItem FindVisualChild<childItem>(DependencyObject obj)
            where childItem : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is childItem)
                    return (childItem)child;
                else
                {
                    childItem childOfChild = FindVisualChild<childItem>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }

            return null;
        }

        private static object GetChildHelper(ListView listView, ListViewItem lvItem, string name)
        {
            Border border = VisualTreeHelper.GetChild(lvItem, 0) as Border;
            ContentPresenter contentPresenter = VisualTreeHelper.GetChild(border, 0) as ContentPresenter;
            return listView.ItemTemplate.FindName(name, contentPresenter);
        }

        private static IEnumerable<FrameworkElement> EnumerateAllControls(FrameworkElement parentControl)
        {
            foreach (Object child in LogicalTreeHelper.GetChildren(parentControl))
            {
                FrameworkElement childFrameworkElement = child as FrameworkElement;
                if (childFrameworkElement != null)
                {
                    yield return childFrameworkElement;

                    foreach (FrameworkElement grandChild in EnumerateAllControls(childFrameworkElement))
                        yield return grandChild;
                }
            }
        }
    }
}
